package main

import (
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/therecipe/qt/core"
	"github.com/therecipe/qt/gui"
	"github.com/therecipe/qt/quick"
)

func init() {
	verbose = true
	step = 1
}

var (
	buf     string
	bot     *Bot
	target  string
	step    int
	verbose bool
)

func isZero(s string) bool {
	return len(s) == 0
}

func doLogin(server, channel, nick, pwd string, s *QmlBridge) {
	if isZero(server) || isZero(channel) || isZero(nick) || isZero(pwd) {
		panic("error input")
	}
	bot.server = server
	bot.User = nick
	bot.Nick = bot.User
	bot.Channel = fmt.Sprintf("#xtalk%s", channel)

	target = bot.Channel

	bot.Crypto.SetKey(pwd)

	info := fmt.Sprintf("%s / %s / %s", server, target, nick)
	s.SetHeader(info)

	step = 2

	go doRecv(s)
}

//doRecv work in goroutine
func doRecv(s *QmlBridge) {
	bot.Connect()
	//defer quit()
	bot.Command("MODE", bot.Channel, "+s")
	for {
		message, err := bot.Recv()
		if err != nil {
			s.AppendMsg("sys", "Exit Now!")
			break
		}
		//fmt.Println(message.Command, message.Params)

		if message.Command == "JOIN" {
			//connected
			s.AppendMsg(message.Prefix.Name, message.Command)
			if step < 3 && message.Prefix.Name == bot.Nick {
				step = 3
			}
			if message.Prefix.Name != bot.Nick {
				s.AppendUser(message.Prefix.Name)
			}
		} else if message.Command == "QUIT" {
			s.AppendMsg(message.Prefix.Name, message.Command)
			s.RemoveUser(message.Prefix.Name)
		} else if message.Command == "PING" {
			bot.Send(fmt.Sprintf("PONG %d", time.Now().UnixNano()))
			//log.Println("SEND: PONG")
		} else if message.Command == "PRIVMSG" {
			// Do Something with this msg
			rmsg := message.Params[1]
			dmsg := bot.Crypto.Decode(rmsg)
			name1 := message.Prefix.Name
			var msg string
			if dmsg == nil {
				msg = fmt.Sprintf("%s %s", "[not secret]", rmsg)
				s.AppendMsg(string(name1), msg)
			} else {
				msg = string(dmsg)
				s.AppendMsg(string(name1), msg)
			}
		} else if message.Command == "353" {
			names := strings.Split(message.Params[3], " ")
			for _, v := range names {
				s.AppendUser(v)
			}
		} else if verbose {
			//log.Printf("%v\n", message)
			msg := fmt.Sprintf("%s:%s", message.Command, strings.Join(message.Params, ","))
			//log.Println(msg)
			s.AppendMsg(message.Prefix.Name, msg)
		}
	}
}

func RunMain() {
	//defer gettext.SaveLog()
	bot = new(Bot)
	core.QCoreApplication_SetAttribute(core.Qt__AA_EnableHighDpiScaling, true)

	gui.NewQGuiApplication(len(os.Args), os.Args)
	gui.QGuiApplication_SetApplicationDisplayName("cuichat")

	var view = quick.NewQQuickView(nil)

	bridge := NewQmlBridge(nil)
	bridge.ConnectSendUserMsg(func(data string) {
		//fmt.Println(target, data)
		bot.PrivMsgTo(target, data)
		bridge.AppendMsg(bot.Nick, data)
	})

	bridge.ConnectLogin(func(server, channel, nick, pwd string) {
		doLogin(server, channel, nick, pwd, bridge)
	})

	view.RootContext().SetContextProperty("QmlBridge", bridge)

	view.SetSource(core.NewQUrl3("qrc:/qml/login.qml", 0))
	view.SetResizeMode(quick.QQuickView__SizeRootObjectToView)
	view.SetTitle("main view")
	view.Show()
	gui.QGuiApplication_Exec()
	bot.Close()
}

func main() {
	RunMain()
}
